﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using WiimoteLib;

namespace WiiWatcher
{
    public partial class Sheet1 {
        private Wiimote mWiimote;

        Timer mTimer = new Timer();
        List<WiimoteState> mStates = new List<WiimoteState>();

        private void Sheet1_Startup(object sender, System.EventArgs e) {
            mTimer.Interval = 100;
            mTimer.Tick += new EventHandler(mTimer_Tick);
        }

        private void Sheet1_Shutdown(object sender, System.EventArgs e) {
            DisconnectWiimote();
        }

        #region VSTO Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.butnStart.Click += new System.EventHandler(this.butnStart_Click);
            this.butnTest.Click += new System.EventHandler(this.butnTest_Click);
            this.Shutdown += new System.EventHandler(this.Sheet1_Shutdown);
            this.Startup += new System.EventHandler(this.Sheet1_Startup);

        }

        #endregion

        private void butnStart_Click(object sender, EventArgs e) {
            if (mWiimote == null) {
                ConnectWiimote();
                mStates.Clear();
                butnStart.Text = "Stop";
                mTimer.Enabled = true;
            } else {
                mTimer.Enabled = false;
                butnStart.Text = "Start";
                DisconnectWiimote();
                ProcessStates();
            }
        }

        Excel.Worksheet NewResultSheet() {
            var xResult = (Excel.Worksheet)Globals.ThisWorkbook.Sheets.Add(missing, Globals.ThisWorkbook.Sheets[Globals.ThisWorkbook.Sheets.Count], missing, missing);
            xResult.Name = "Results " + (Globals.ThisWorkbook.Sheets.Count - 1);
            xResult.Cells[1, 1] = "Button A";
            xResult.Cells[2, 1] = "Button B";
            xResult.Cells[3, 1] = "Home";
            xResult.Cells[4, 1] = "One";
            xResult.Cells[5, 1] = "Two";
            xResult.Cells[6, 1] = "Plus";
            xResult.Cells[7, 1] = "Minus";
            xResult.Cells[8, 1] = "Up";
            xResult.Cells[9, 1] = "Down";
            xResult.Cells[10, 1] = "Left";
            xResult.Cells[11, 1] = "Right";
            xResult.Cells[12, 1] = "Accel X";
            xResult.Cells[13, 1] = "Accel Y";
            xResult.Cells[14, 1] = "Accel Z";
            return xResult;
        }

        void ProcessStates() {
            var xSheet = NewResultSheet();
            int xCol = 1;
            foreach (var xState in mStates) {
                xCol++;
                xSheet.Cells[1, xCol] = xState.ButtonState.A;
                xSheet.Cells[2, xCol] = xState.ButtonState.B;
                xSheet.Cells[3, xCol] = xState.ButtonState.Home;
                xSheet.Cells[4, xCol] = xState.ButtonState.One;
                xSheet.Cells[5, xCol] = xState.ButtonState.Two;
                xSheet.Cells[6, xCol] = xState.ButtonState.Plus;
                xSheet.Cells[7, xCol] = xState.ButtonState.Minus;
                xSheet.Cells[8, xCol] = xState.ButtonState.Up;
                xSheet.Cells[9, xCol] = xState.ButtonState.Down;
                xSheet.Cells[10, xCol] = xState.ButtonState.Left;
                xSheet.Cells[11, xCol] = xState.ButtonState.Right;
                xSheet.Cells[12, xCol] = xState.AccelState.X;
                xSheet.Cells[13, xCol] = xState.AccelState.Y;
                xSheet.Cells[14, xCol] = xState.AccelState.Z;
                //xState.AccelState
                //xState.Battery
                //xState.IRState
                //xState.NunchukState
            }
            mStates.Clear();
        }

        void mTimer_Tick(object sender, EventArgs e) {
            var xStateCopy = new WiimoteState();
            var xState = mWiimote.WiimoteState;
            xStateCopy.ButtonState.A = xState.ButtonState.A;
            xStateCopy.ButtonState.B = xState.ButtonState.B;
            xStateCopy.ButtonState.Home = xState.ButtonState.Home;
            xStateCopy.ButtonState.One = xState.ButtonState.One;
            xStateCopy.ButtonState.Two = xState.ButtonState.Two;
            xStateCopy.ButtonState.Plus = xState.ButtonState.Plus;
            xStateCopy.ButtonState.Minus = xState.ButtonState.Minus;
            xStateCopy.ButtonState.Up = xState.ButtonState.Up;
            xStateCopy.ButtonState.Down = xState.ButtonState.Down;
            xStateCopy.ButtonState.Left = xState.ButtonState.Left;
            xStateCopy.ButtonState.Right = xState.ButtonState.Right;
            xStateCopy.AccelState.X = xState.AccelState.X;
            xStateCopy.AccelState.Y = xState.AccelState.Y;
            xStateCopy.AccelState.Z = xState.AccelState.Z;
            mStates.Add(xStateCopy);
        }

        public void ConnectWiimote() {
            try {
                mWiimote = new Wiimote();
                mWiimote.AltWriteMethod = false;
                mWiimote.OnWiimoteChanged += new WiimoteChangedEventHandler(mWiimote_OnWiimoteChanged);
                mWiimote.Connect();
            } catch {
                mWiimote.Dispose();
                mWiimote = null;
            }
            if (mWiimote != null)
            {
                mWiimote.SetReportType(Wiimote.InputReport.IRAccel, true);

                mWiimote.SetRumble(true);
                System.Threading.Thread.Sleep(50);
                mWiimote.SetRumble(false);
            }
        }

        void mWiimote_OnWiimoteChanged(object sender, WiimoteChangedEventArgs args) {
            // This event often happens after disposal, need to clean it up
            try {
                if (args.WiimoteState.Extension) {
                    mWiimote.SetReportType(Wiimote.InputReport.IRExtensionAccel, true);
                } else {
                    mWiimote.SetReportType(Wiimote.InputReport.IRAccel, true);
                }
            } catch { }
        }

        public void DisconnectWiimote() {
            if (mWiimote != null) {
                mWiimote.Disconnect();
                mWiimote.Dispose();
                mWiimote = null;
            }
        }

        private void butnTest_Click(object sender, EventArgs e) {
            NewResultSheet();
        }

    }
}
